using QFramework;
using UnityEngine;

namespace SnakeGame
{
    public interface IGridMapSystem : ISystem
    {
        Node GetNode(int x, int y);
        void SetNodeRotation(Vector2Int pos, float angle);
        void SetNodeState(int x, int y, Node.E_State state);
        void SetNodeState(Vector2Int pos, Node.E_State state);
        void SetNodeState(Node node, Node.E_State state);
        void InitGrid(int w, int h);
    }
    public class GridMapSystem : AbstractSystem, IGridMapSystem
    {
        private Node[,] mGridMap;

        private Sprite mWallSprite;
        private Sprite mFoodSprite;
        private Sprite mSnakeSprite;

        private Transform mGameRoot;

        protected override void OnInit()
        {
            mWallSprite = Resources.Load<Sprite>("Sprites/Block");
            mFoodSprite = Resources.Load<Sprite>("Sprites/Circle");
            mSnakeSprite = Resources.Load<Sprite>("Sprites/Triangle");

            if (mGameRoot == null) mGameRoot = new GameObject("GameMap").AddComponent<GameRoot>().transform;
        }
        Node IGridMapSystem.GetNode(int x, int y) => mGridMap[y, x];
        void IGridMapSystem.SetNodeState(int x, int y, Node.E_State state)
        {
            mGridMap[y, x].UpdateState(state, SetNodeStyle);
        }
        void IGridMapSystem.SetNodeState(Vector2Int pos, Node.E_State state)
        {
            mGridMap[pos.y, pos.x].UpdateState(state, SetNodeStyle);
        }
        void IGridMapSystem.SetNodeState(Node node, Node.E_State state)
        {
            node.UpdateState(state, SetNodeStyle);
        }
        void IGridMapSystem.SetNodeRotation(Vector2Int pos, float angle)
        {
            mGridMap[pos.y, pos.x].SetRotation(angle);
        }
        void IGridMapSystem.InitGrid(int w, int h)
        {
            if (mGridMap == null || mGridMap.GetLength(0) * mGridMap.GetLength(1) < w * h) mGridMap = new Node[w, h];
            for (int row = 0; row < w; row++)
            {
                for (int col = 0; col < h; col++)
                {
                    if (mGridMap[row, col] == null) mGridMap[row, col] = new Node($"Node{row}{col}", mGameRoot);
                    mGridMap[row, col].SetPos(col, row);
                    mGridMap[row, col].UpdateState(row == 0 || row == w - 1 || col == 0 || col == h - 1 ?
                        Node.E_State.Wall : Node.E_State.Blank, SetNodeStyle);
                }
            }
        }
        private void SetNodeStyle(Node.E_State state, SpriteRenderer sp)
        {
            switch (state)
            {
                case Node.E_State.Blank:
                    sp.sprite = mWallSprite;
                    sp.color = Color.gray;
                    break;
                case Node.E_State.Wall:
                    sp.sprite = mWallSprite;
                    sp.color = Color.black;
                    break;
                case Node.E_State.Snake:
                    sp.sprite = mSnakeSprite;
                    sp.color = Color.cyan;
                    break;
                case Node.E_State.Food:
                    sp.sprite = mFoodSprite;
                    sp.color = Color.yellow;
                    break;
            }
        }
    }
}